#include "decodepacket.h"
#include <QDebug>

DecodePacket::DecodePacket() {

}

bool DecodePacket::openDecoder(AVCodecParameters *params)
{
    if (params == nullptr){
        return false;
    }
    //找到解码器
    const AVCodec *avcodec = avcodec_find_decoder(params->codec_id);
    if (avcodec == nullptr){
        avcodec_parameters_free(&params);
        qDebug() << "DecodePacket::can't find the avcodec id " << params->codec_id;
        return false;
    }
    qDebug() << "DecodePacket::find the avcodec " << params->codec_id;
    avCodecCtx = avcodec_alloc_context3(avcodec);

    ///配置解码器上下文参数
    avcodec_parameters_to_context(avCodecCtx, params);
    //八线程解码
    avCodecCtx->thread_count = 8;

    //打开解码器上下文
    int re = avcodec_open2(avCodecCtx, NULL, NULL);
    if (re != 0){
        avcodec_free_context(&avCodecCtx);
        qDebug() << "DecodePacket::avcodec_open2 failed!";
        return false;
    }
    qDebug() << "DecodePacket::avcodec_open2 success!";
    return true;
}

bool DecodePacket::sendToDecoder(AVPacket *pkt)
{
    //容错处理
    if (pkt == nullptr || pkt->size <= 0 || pkt->data == nullptr){
        return false;
    }
    if (avCodecCtx == nullptr){
        return false;
    }
    //发送packet给解码器
    int ret = avcodec_send_packet(avCodecCtx,pkt);
    //引用计数--
    av_packet_free(&pkt);
    if (ret != 0){
        char buf[1024] = { 0 };
        av_strerror(ret, buf, sizeof(buf) - 1);
        qDebug() << "DemuxMedia::readPacket()" << buf;
        return false;
    }
    return true;
}

AVFrame *DecodePacket::receiveFrame()
{
    if (avCodecCtx == nullptr){
        return nullptr;
    }
    AVFrame *frame = av_frame_alloc();
    //从解码器获取解码出来的原始数据
    int ret = avcodec_receive_frame(avCodecCtx, frame);
    if (ret != 0)
    {
        av_frame_free(&frame);
        return nullptr;
    }
    return frame;
}
